package cn.zyx.sys.web;

import cn.zyx.common.GlobalAjaxJson;
import cn.zyx.common.entity.Page;
import cn.zyx.common.utils.sys.*;
import cn.zyx.sys.entity.Menu;
import cn.zyx.sys.entity.Role;
import cn.zyx.sys.entity.User;
import cn.zyx.sys.service.RoleService;
import cn.zyx.sys.service.UserService;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set;


/**
 * 用户Controller
 * @author zyx
 */
@RestController
@RequestMapping("/sys/user")
@Api(tags ="用户管理")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    //特殊操作用户列表：操作--特殊用户不允许删除- 页面
    @Value("${superUser}")
    private String superUser;

    @RequiresPermissions(value = {"sys:user:add", "sys:user:edit"}, logical = Logical.OR)
    @PostMapping("save")
    @ApiOperation(value = "保存用户")
    public GlobalAjaxJson save(User user) {
        if (user.getLoginName().contains("access-key")) {
            return GlobalAjaxJson.error("保存用户'" + user.getLoginName() + "'失败，登录名不能包含access-key!");
        }
        // 如果新密码不为空，则更换密码
        if (StringUtils.isNotBlank(user.getNewPassword())) {
            // 密码加盐加密
            user.setPassword(userService.entryptPassword(user.getNewPassword()));
        }
        // 检查登录名
        if (!isCheckLoginName(user.getOldLoginName(), user.getLoginName())) {
            return GlobalAjaxJson.error("保存用户'" + user.getLoginName() + "'失败，登录名已存在!");
        }
        // 角色数据有效性验证，过滤不在授权内的角色
        List<Role> roleList = Lists.newArrayList();
        List<String> roleIdList = user.getRoleIdList();
        for (String roleId : roleIdList) {
            roleList.add(roleService.get(roleId));
        }
        user.setRoleList(roleList);
        // 保存用户信息
        userService.saveUser(user);
        // 清除当前用户缓存
        if (user.getLoginName().equals(UserUtils.getUser().getLoginName())) {
            UserUtils.clearCache();
        }
        return GlobalAjaxJson.success("保存用户'" + user.getLoginName() + "'成功!");
    }

    /**
     * 批量删除用户
     */
    @ApiOperation(value = "删除用户")
    @RequiresPermissions("sys:user:del")
    @DeleteMapping("delete")
    public GlobalAjaxJson delete(String ids) {
        String idArray[] = ids.split(",");
        String usersNo []= superUser.split(",");
        StringBuffer msg = new StringBuffer();
        boolean success = true;
        for (String id : idArray) {
            User user = userService.get(id);
            if (UserUtils.getUser().getId().equals(user.getId())) {
                success = false;
                msg.append("["+user.getLoginName()+"]删除失败，不允许删除当前用户!<br/>");
            }
            // 验证指定用户可以删除
            else if (User.isSuperUser(user.getLoginName(),usersNo)) {
                success = false;
                msg.append("["+user.getLoginName()+"]删除失败，不允许删除超级管理员!<br/>");
            } else {
                msg.append("["+user.getLoginName()+"]删除成功!<br/>");
                userService.deleteUser(user);//删除用户成功
            }
        }
        if (success){
            return GlobalAjaxJson.success(msg.toString());
        } else {
            return GlobalAjaxJson.error(msg.toString());
        }
    }

    /**
     * 检查用户的登录名
     * @param oldLoginName
     * @param loginName
     * @return
     */
    private boolean isCheckLoginName(String oldLoginName, String loginName) {
        if (loginName != null && loginName.equals(oldLoginName)) {
            return true;
        } else if (loginName != null && userService.getUserByLoginName(loginName) == null) {
            return true;
        }
        return false;
    }

    /**
     * 根据用户名查询用户
     * @param userName
     * @return
     */
    @GetMapping("getUserByLoginName")
    @ApiOperation(value = "根据用户名查询用户")
    @RequiresPermissions("sys:user:list")
    public GlobalAjaxJson getUserByLoginName(String userName) {
        User user = userService.getUserByLoginName(userName);
        return GlobalAjaxJson.success().put("user", user);
    }

    /**
     *
     * 1. 自定义的shiro过滤器会对请求进行拦截（jwtFilter）
     *     1.1 设置跨域
     *     1.2 检查token，将token交给realm
     * 2. realm 的 认证函数doGetAuthenticationInfo 会检查token，判断用户名和密码是否正确
     * 3. realm 的 授权函数doGetAuthorizationInfo 会设置用户的权限信息
     * 查询分页数据
     *
     * @param user
     * @return
     */
    //@RequiresPermissions("sys:user:list")
    @GetMapping("list")
    public GlobalAjaxJson list(User user, HttpServletRequest request, HttpServletResponse response) {
        Page<User> page = userService.findPage(new Page<User>(request, response), user);
        return GlobalAjaxJson.success().put("page", page);
    }

    @ApiOperation(value = "登录前获取用户")
    @GetMapping("getMenus")
    @RequiresPermissions("user")
    public GlobalAjaxJson getMenus() {
        GlobalAjaxJson j = new GlobalAjaxJson();
        // 获取字典列表
        j.put("dictList", DictUtils.getDictMap());
        // 获取用户权限数据
        j.put("permissions", this.getPermissions());
        j.put("menuList", MenuUtils.getMenus());
        j.put("routerList", RouterUtils.getRoutersByMenu());
        return j;
    }

    @ApiOperation(value = "获取用户权限")
    @RequiresPermissions("user")
    @GetMapping("getPermissions")
    public Set<String> getPermissions() {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        String token = UserUtils.getToken();
        String loginName = JWTUtils.getLoginName(token);
        User user = UserUtils.getByLoginName(loginName);
        if (user != null) {

            List<Menu> list = UserUtils.getMenuList();
            for (Menu menu : list) {
                if (org.apache.commons.lang3.StringUtils.isNotBlank(menu.getPermission())) {
                    // 添加基于Permission的权限信息
                    for (String permission : org.apache.commons.lang3.StringUtils.split(menu.getPermission(), ",")) {
                        info.addStringPermission(permission);
                    }
                }
            }
            // 添加用户权限
            info.addStringPermission("user");
            // 添加用户角色信息
            for (Role role : user.getRoleList()) {
                info.addRole(role.getEnname());
            }
        }
        return info.getStringPermissions();
    }

    /**
     * 返回用户信息
     *
     * @return
     */
    @RequiresPermissions("user")
    @GetMapping("info")
    @ApiOperation(value = "获取当前用户信息")
    public GlobalAjaxJson infoData() {
        return GlobalAjaxJson.success("获取个人信息成功!").put("role", UserUtils.getRoleList()).put("user", UserUtils.getUser());
    }

}
